package cn.sczc.jh.client.controller.option;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.sczc.jh.client.base.AbstractController;
import cn.sczc.jh.client.entity.SecurityMaterials;
import cn.sczc.jh.client.entity.User;
import cn.sczc.jh.client.service.securityMaterials.SecurityMaterialsService;
import cn.sczc.jh.client.util.BmUtils;
import cn.sczc.jh.client.util.DownloadExcelUtil;
import cn.sczc.jh.client.util.ExlVo;
import cn.sczc.jh.client.util.PageUtils;
import jxl.format.BorderLineStyle;

@Controller
@RequestMapping({ "/option/asset" })
public class AssetViewController extends AbstractController{
	@Autowired
	private SecurityMaterialsService securityMaterialsService;
	
	@GetMapping()
	public String index(Model model) {
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		model.addAttribute("permissionList",user.getPermissions());
		model.addAttribute("userId", user.getId().toString());
		model.addAttribute("tenantId", user.getTenantId().toString());
		model.addAttribute("userName", user.getUsername());
		model.addAttribute("teamList", user.getTeams());
		return "option/asset/asset";
	}
	
	@GetMapping("/list")
	@ResponseBody
	public ResponseEntity<?> list(@RequestParam Map<String, Object> params) {
		Map<String, Object> pageParams = new HashMap<>();
		pageParams.put("pageNum", params.get("pageNumber"));
		pageParams.put("pageSize", params.get("pageSize"));
		@SuppressWarnings("unchecked")
		Page<SecurityMaterials> page = (Page<SecurityMaterials>) super.getPage(pageParams);
		Page<SecurityMaterials> data = securityMaterialsService.queryList(page,params);
		PageUtils pageUtil = new PageUtils(data.getRecords(), (int) data.getTotal());
		return ResponseEntity.ok(pageUtil);
	}
	
	@PostMapping("/queryAssetDataList")
	@ResponseBody
	public ResponseEntity<?> queryAssetDataList() {
		Map<String, Object> params = new HashMap<>();
		List<SecurityMaterials> allList = securityMaterialsService.queryListNoPage(params);
		return ResponseEntity.ok(allList);
	}
	

	@PostMapping("/save")
	@ResponseBody
	public ResponseEntity<?> save(@RequestBody SecurityMaterials entity) {
		Boolean result = securityMaterialsService.insert(entity);
		return ResponseEntity.ok(result);
	}
	
	@PostMapping("/qryById/{id}")
	@ResponseBody
	public ResponseEntity<?> qryById(@PathVariable("id") String id) {
		SecurityMaterials s = securityMaterialsService.qryById(id);
		return ResponseEntity.ok(s);
	}
	
	@PostMapping("/del/{id}")
	@ResponseBody
	public ResponseEntity<?> del(@PathVariable("id") String id) {
		Boolean result = securityMaterialsService.del(id);
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 安防物资数据导出
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "downLoadAssetEXL")
	public String downLoadAssetEXL(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		//取出带查询条件的所有数据allList
		String p = request.getParameter("param").toString();
//		String param = new String(p.getBytes("ISO8859-1"), "UTF-8");
		@SuppressWarnings("unchecked")
		Map<String, Object> params = JSON.parseObject(p, HashMap.class);
		List<SecurityMaterials> allList = securityMaterialsService.queryListNoPage(params);
		if (allList!=null&&allList.size()>0) {
			//循环sheet
			DownloadExcelUtil dExlUtile = null;
			int dataNum = 1;
			for (SecurityMaterials item : allList) {
					//设置对象：title，value ，List<entity>
					StringBuffer sb = new StringBuffer();
					sb.append("*名称_");
					sb.append(item.getSmName()!=null?item.getSmName():"-");
					sb.append("$");
					sb.append("*数量_");
					sb.append(item.getSmNum()!=null?item.getSmNum():"0");
					sb.append("$");
					sb.append("*正常数量_");
					sb.append(item.getSmNormalNum()!=null?item.getSmNormalNum():"0");
					sb.append("$");
					sb.append("*异常数量_");
					sb.append(item.getSmAbnormalNum()!=null?item.getSmAbnormalNum():"0");
					sb.append("$");
					sb.append("*到期数量_");
					sb.append(item.getSmExpireNum()!=null?item.getSmExpireNum():"0");
					sb.append("$");
					sb.append("*未到期数量_");
					sb.append(item.getSmUnexpiredNum()!=null?item.getSmUnexpiredNum():"0");
					String tvsb = sb.toString();
					String[] tvsbArray = tvsb.split("\\$");
					List<ExlVo> entityList = new ArrayList<ExlVo>();
					if (tvsbArray.length>0) {
						for (String tv : tvsbArray) {
							ExlVo entity = new ExlVo();
							String[] tvArray = tv.split("_");
							entity.setTitle(tvArray[0]);
							entity.setValue(tvArray.length==1?"-":tvArray[1]);
							entityList.add(entity);
						}
					}
					if (dataNum == 1) {//若为第一次循环
						//在response中写入exl。传入当前type的name，和文件名：DownloadExcelUtil
						dExlUtile = new DownloadExcelUtil(response,"安防物资数据","安防物资数据");
						//把list<entity>中的title按list的顺序放入String【】，调用：setExcelListTitle
						String[] titleArray = new String[entityList.size()];
						for (int i = 0; i < entityList.size(); i++) {
							titleArray[i] = entityList.get(i).getTitle();
						}
						dExlUtile.addRow(titleArray, BorderLineStyle.THIN,jxl.format.Alignment.CENTRE, "bold");
						//dExlUtile.setExcelListTitle(titleArray);
						//把list<entity>中的value按list的顺序放入String【】，调用：addRow
						String[] valueArray = new String[entityList.size()];
						for (int i = 0; i < entityList.size(); i++) {
							valueArray[i] = entityList.get(i).getValue();
						}
						dExlUtile.addRow(valueArray, BorderLineStyle.THIN,jxl.format.Alignment.CENTRE, "");
					}else {
						//把list<entity>中的value按list的顺序放入String【】，调用：addRow
						String[] valueArray = new String[entityList.size()];
						for (int i = 0; i < entityList.size(); i++) {
							valueArray[i] = entityList.get(i).getValue();
						}
						dExlUtile.addRow(valueArray, BorderLineStyle.THIN,jxl.format.Alignment.CENTRE, "");
					}									
					dataNum++;
			}
		          dExlUtile.reportExcel();
			
		}else {
			//查询结果为空
		}
		return null;
	}
	
	@ResponseBody
	@RequestMapping(value = "assetFileUpload", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
	public String fileUpload(@RequestParam(value = "file", required = false) MultipartFile file,HttpServletRequest request)throws Exception {
		List<String> dataList=new ArrayList<String>();
		//导入Excel操作
		//导入Excel文件不为空时，将文件写入流，然后转化为工作薄
		if (file!=null){
			try {	
				Workbook workBook = null;
				String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length());
				if(!"xls".equals(fileType)&&!"xlsx".equals(fileType)){
					return "请选择excel格式文件！";
				}
				int header=0;
				workBook = WorkbookFactory.create(file.getInputStream());
				if (workBook.getNumberOfSheets()>0){
					//获取第一个单元薄
					Sheet sheet = workBook.getSheetAt(0);
					String fixedTitle = "*名称$*数量$*正常数量$*异常数量$*到期数量$*未到期数量";
					String finalTile = fixedTitle;
					Row rowHead = sheet.getRow(header); 
					if (rowHead != null) {
						String[] headNames = new String[rowHead.getLastCellNum()];
						// 获取该行中总共有多少列数据row.getLastCellNum()
						for (int j = 0; j < rowHead.getLastCellNum(); j++) {
							Cell cell = rowHead.getCell(j);
							if (cell == null) {
								continue;
							} else {
								// 获取表头各个字段名称
								String returnStr = BmUtils.getCellValue(cell);
								headNames[j] = returnStr;
							}
						}
						if (headNames!=null&&headNames.length>0) {
							for (String name : headNames) {
								if (finalTile.indexOf(name)==-1) {
									return "文件列头不正确！";
								}
							}
						}
						List<SecurityMaterials> smList = new ArrayList<SecurityMaterials>();
						Date date = new Date();
						// 遍历单元簿中每一行，获取每一列字段，并根据表头对应赋值
						int flag=2;
						for (int i = header; i < sheet.getPhysicalNumberOfRows(); i++) {
							Row row = sheet.getRow(i + 1);
							Boolean isRow = isRowEmpty(row);
							SecurityMaterials sm = null;
							if (!isRow) {
								String rowError="第"+flag+"行   ";
								String data="";
								sm = new SecurityMaterials();
								//sm.setTypeId(typeId);
								sm.setOid(UUID.randomUUID().toString());
								//sm.setCreateBy(WebUtil.getCurrentUser());
								sm.setCreateTime(date);
								// 获取该行中总共有多少列数据row.getLastCellNum()
								for (int j = 0; j < row.getLastCellNum(); j++) {
									Cell cell = row.getCell(j);
									if (cell == null) {
										continue;
									} else if (StringUtils.hasText(headNames[j])) {
										// 获取单元格内容，并根据单元格类型，进行转化
										String returnStr = BmUtils.getCellValue(cell);
										// 根据给定的Excel格式，进行导入，一下是对应列对应字段
										if (headNames[j].equals("*名称")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												sm.setSmName(returnStr);
											}else {
												data += "名称不能为空;";
											}
										}else if (headNames[j].equals("*数量")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												Boolean b = isNumeric(returnStr);
												if (b) {
													sm.setSmNum(Integer.valueOf(returnStr));
												}else {
													data += "数量格式不正确;";
												}
											}else {
												data += "数量不能为空;";
											}
										}else if (headNames[j].equals("*正常数量")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												Boolean b = isNumeric(returnStr);
												if (b) {
													sm.setSmNormalNum(Integer.valueOf(returnStr));
												}else {
													data += "正常数量格式不正确;";
												}
											}else {
												data += "正常数量不能为空;";
											}
										}else if (headNames[j].equals("*异常数量")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												Boolean b = isNumeric(returnStr);
												if (b) {
													sm.setSmAbnormalNum(Integer.valueOf(returnStr));
												}else {
													data += "异常数量格式不正确;";
												}
											}else {
												data += "异常数量不能为空;";
											}
										}else if (headNames[j].equals("*到期数量")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												Boolean b = isNumeric(returnStr);
												if (b) {
													sm.setSmExpireNum(Integer.valueOf(returnStr));
												}else {
													data += "到期数量格式不正确;";
												}
											}else {
												data += "到期数量不能为空;";
											}
										}else if (headNames[j].equals("*未到期数量")) {
											if(returnStr!=null&&!"".equals(returnStr)){
												Boolean b = isNumeric(returnStr);
												if (b) {
													sm.setSmUnexpiredNum(Integer.valueOf(returnStr));
												}else {
													data += "未到期数量格式不正确;";
												}
											}else {
												data += "未到期数量不能为空;";
											}
										}
									}
								}
								flag++;
								if (sm.getSmNum()!=sm.getSmAbnormalNum()+sm.getSmNormalNum()) {
									data += "正常数量和异常数量的和不等于数量;";
								}
								if (sm.getSmNum()!=sm.getSmExpireNum()+sm.getSmUnexpiredNum()) {
									data += "到期数量和未到期数量的和不等于数量;";
								}
								if(data!=null&&!"".equals(data)){
									dataList.add(rowError);
									dataList.add(data);
								}
								smList.add(sm);
							}
						}
						if(dataList!=null&&dataList.size()>0){
							String data="";
							for(String errorData:dataList){
								data+=errorData;
							}
							return data;
						}else{
							//存数据
							if(smList != null && smList.size() > 0) {
								securityMaterialsService.batchInsert(smList);
								return "导入成功";
							} else {
								return "文件数据为空!";
							}
						}
						
					}
				}
			}catch (IOException e) {
				return "未知异常!";
			}
		}
		return "无文件!";
	}
	
	@SuppressWarnings("deprecation")
	public static boolean isRowEmpty(Row row) {
		if (row==null) {
			return true;
		}else {
			for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
			       Cell cell = row.getCell(c);
			       if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
			           return false;
			   }
			   return true;
		}
	}
	
	public static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if( !isNum.matches() ){
            return false;
        }
        return true;
	}
	
	public static boolean isValidDate(String datePattern,String str) {
	      boolean convertSuccess=true;
	       SimpleDateFormat format = new SimpleDateFormat(datePattern);
	       try {
	          format.setLenient(false);
	          format.parse(str);
	       } catch (Exception e) {
	           convertSuccess=false;
	       } 
	       return convertSuccess;
	}
	
}
